package com.hvisions.server.controller;

import com.hvisions.config.OpcUaConfig;
import com.hvisions.server.model.TbOpcPoint;
import com.hvisions.server.service.ITbOpcPointService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author ykz
 */
@RestController
@RequestMapping(value = "/OpcSub")
@Api(value = "opc订阅控制器")
public class OPCUAController {

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    ITbOpcPointService pointService;

    /**
     * 读取指定点位信息
     * @param point
     * @return
     * @throws Exception
     */
    @GetMapping(value = "/read/{point}")
    public String read(@PathVariable(value = "point")String point) throws Exception {
        return OpcUaConfig.readNode(point).toString();
    }

    /**
     * 增加订阅点位
     * @param points
     * @return true:成功 false:失败
     */
    @PostMapping(value = "/addSubscribe")
    public Boolean addSubscribe(@RequestBody List<TbOpcPoint> points){
        List<String> strings = redisTemplate.opsForList().range("opc:point",0,-1);
        //判断是否有重复订阅点
        Integer size = strings.stream().map(t->
            points.stream().filter(p-> t.equals(p.getPoint())).findAny().orElse(null)).filter(Objects::nonNull)
                .collect(Collectors.toList())
                .size();
        if(size>0){
            return false;
        }
        //保存数据库
        if(pointService.saveBatch(points)){
            redisTemplate.opsForList().rightPushAll("opc:point",points.stream().map(t->t.getPoint()).collect(Collectors.toList()));
            //todo:此处建议指定一个永久测试点，并立马写值强制变化，而且该点必须在订阅中，因为新增加的点位信息不能及时读取，得等别的点位变化后，才会开始订阅
            return true;
        }
        return false;
    }

    /**
     * 移除订阅点
     * @param point
     * @return
     */
    @PutMapping(value = "/removeSubscribePoint")
    public Boolean removeSubscribePoint(@RequestBody TbOpcPoint point){
        List<String> strings = redisTemplate.opsForList().range("opc:point",0,-1);
        if(!strings.contains(point.getPoint())){
            return false;
        }
        //删除数据
        if(pointService.removeById(point.getId())){
            redisTemplate.opsForList().remove("opc:point",0,point.getPoint());
            return true;
        }
        return false;
    }



}
